package aspectjlib.logging;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import aspectjlib.enums.CurrentAspect;

public class ThreadTracker {
	private Map<String, Integer> objs;
	private List<Long> times;
	private CurrentAspect cae;
	private final Logger logger = Logger.getLogger(MasterTracker.class.getName());
	
	public ThreadTracker(String functionId, Long starttime, CurrentAspect cae) {
		this.cae = cae;
		this.objs = new HashMap<String,Integer>();
		this.times = new ArrayList<Long>();
		add(functionId, starttime);
	}
	
	public void add(String functionId, Long starttime) {
		if (cae.equals(CurrentAspect.METHODTOUCHES)) {
			if (objs.containsKey(functionId))
				objs.put(functionId, objs.get(functionId) + 1);
			else
				objs.put(functionId, 1);
		}
		times.add(starttime);
	}
	
	public Long remove() {
		if (cae.equals(CurrentAspect.METHODTOUCHES) && times.size() == 1){
			Map<String, Integer> tm = sortByValue(objs);
			for (Map.Entry<String, Integer> obj : tm.entrySet()) {
				logger.debug(obj.getKey() + "," + Thread.currentThread().getId() + "," + obj.getValue());
			}
		}
		return times.remove(times.size() - 1);
	}
	
	
	// Code inspired by from http://www.mkyong.com/java/how-to-sort-a-map-in-java/
	private Map<String, Integer> sortByValue(Map<String, Integer> unsortMap) {
		 
		List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());
 
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			public int compare(Map.Entry<String, Integer> o2, Map.Entry<String, Integer> o1) {
				return o1.getValue().compareTo(o2.getValue());
			}
		});
 
		Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
		for (Iterator<Entry<String, Integer>> it = list.iterator(); it.hasNext();) {
			Map.Entry<String, Integer> entry = it.next();
			sortedMap.put(entry.getKey(), entry.getValue());
		}
		return sortedMap;
	}
	
}